<?php

namespace app\common\services;

use EasyWeChat\Factory;

class QrCodeService
{
    private int $itemsId;

    public function __construct(int $itemsId)
    {
        $this->itemsId = $itemsId;
    }

    public static function init(int $itemsId)
    {
        return (new self($itemsId));
    }

    /**
     * 公众号服务
     *
     * @return \EasyWeChat\OfficialAccount\Application
     */
    public function officialAccount()
    {
        $config = web_config($this->itemsId, 'program.wechat.gzh');
        $defaultConfig = [
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => app()->getRuntimePath() . 'wechat.log',
            ],
            'http' => [
                'timeout' => 5.0, // 超时时间（秒）
                'verify' => app()->getRootPath() . 'cacert.pem'
            ]
        ];
        $config = array_merge($config, $defaultConfig);

        return Factory::officialAccount($config);
    }

    /**
     * 小程序服务
     *
     * @return \EasyWeChat\MiniProgram\Application
     */
    public function miniProgram()
    {
        $config = web_config($this->itemsId, 'program.wechat.mini');
        $defaultConfig = [
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => app()->getRuntimePath() . 'wechat.log',
            ],
            'http' => [
                'timeout' => 5.0, // 超时时间（秒）
                'verify' => app()->getRootPath() . 'cacert.pem'
            ]
        ];
        $config = array_merge($config, $defaultConfig);

        return Factory::miniProgram($config);
    }

    /**
     * 发送模板消息
     *
     * @param $openId
     * @param $templateId
     * @param $data
     * @param $url
     * @param $miniPage
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function sendTemplateMessage($openId, $templateId, $data = [], $url = '', $miniPage = '')
    {
        $param = [
            'touser' => $openId,
            'template_id' => $templateId,
            'url' => $url,
            'data' => $data
        ];
        if ($miniPage) {
            $param['miniprogram'] = [
                'appid' => web_config($this->itemsId, 'program.wechat.mini.appid'),
                'pagepath' => $miniPage
            ];
        }

        return $this->officialAccount()->template_message->send($param);
    }

    /**
     * 获取 scheme 码
     *
     * @param $page
     * @param $query
     * @return mixed
     * @throws \Throwable
     */
    public function miniScheme($page = '', $query = '')
    {
        $cacheKey = md5($page . $query);
        return CacheService::create()->remember($cacheKey, function () use ($page, $query) {
            $server = $this->miniProgram();
            $env_version = web_config($this->itemsId, 'program.wechat.mini.env', 'release');
            $res = $server->url_scheme->generate([
                'jump_wxa' => [
                    'path' => $page,
                    'query' => $query,
                    'env_version' => $env_version
                ],
                'is_expire' => true,
                'expire_type' => 0,
                'expire_time' => time() + 86400
            ]);
            if ($res['errcode'] === 0) {
                return $res['openlink'];
            } else {
                return '';
            }
        }, 86400);
    }

    /**
     * 获取 URL Link
     *
     * @param $page
     * @param $query
     * @return mixed
     * @throws \Throwable
     */
    public function generateUrllink($page = '', $query = '')
    {
        $server = $this->miniProgram();
        $env_version = web_config($this->itemsId, 'program.wechat.mini.env', 'release');
        $res = $server->url_link->generate([
            'path' => $page,
            'query' => $query,
            'is_expire' => true,
            'expire_type' => 0,
            'expire_time' => time() + 86400,
            'env_version' => $env_version,
        ]);
        if ($res['errcode'] === 0) {
            return $res['url_link'];
        } else {
            return '';
        }
    }
}